package com.siwei.infoextract.wrapper.parser;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class DomTreeTraversal {
	private static boolean skipTextNode = true;

	List<DomNodeIteratorCallback> callbacks = new ArrayList<DomNodeIteratorCallback>();
	private DomNode domNode;

	public DomTreeTraversal(DomNode domNode) {
		this.domNode = domNode;
	}

	public void addCallback(DomNodeIteratorCallback callback) {
		this.callbacks.add(callback);
	}
	
	public void removeCallback(DomNodeIteratorCallback callback) {
		this.callbacks.remove(callback);
	}
	
	public void removeCallback(int index) {
		this.callbacks.remove(index);
	}

	public void traverse() {
		DomNodeIteratorCallback callback;

		for (Iterator<DomNodeIteratorCallback> iter = this.callbacks.iterator(); iter.hasNext();) {
			callback = iter.next();
			callback.call(this.domNode);
		}

		internalTraverse(this.domNode);
	}

	private void internalTraverse(DomNode domNode) {
		if (domNode == null || domNode.getChildrenCount() <= 0) {
			return;
		}

		if (skipTextNode && Constraints.TEXT_TAG_NAME.equals(domNode.getName())) {
			return;
		}

		int childrenCount = domNode.getChildrenCount();

		DomNodeIteratorCallback callback;
		for(int i = 0; i < childrenCount; i++) {
			DomNode childDomNode = domNode.getChild(i);

			if (skipTextNode && Constraints.TEXT_TAG_NAME.equals(childDomNode.getName())) {
				continue;
			}

			for (Iterator<DomNodeIteratorCallback> iter = this.callbacks.iterator(); iter.hasNext();) {
				callback = iter.next();
				callback.call(childDomNode);
			}
			internalTraverse(childDomNode);
		}
	}

}
